package org.jeecg.modules.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class HttpClientUtil {
    private static final String DEFAULT_CHARSET = "utf-8";
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
    private static int DEFAULT_CONNECTION_TIMEOUT = 600000;
    private static int DEFAULT_READ_TIMEOUT = 600000;
    //MySQL text最大存储字段
    private static int MAX_TEXT_LENGTH = 21845;


    public static String postRequest(String url, String content, String charset) {
        return postRequest(url, content, "", charset, 60000, 60000, null);
    }

    public static String postRequest(String url, String content, String ContentType, String charset){
        return postRequest(url,content,ContentType,charset,60000,60000);
    }

    public static String postRequest(String url, String content, String ContentType, String charset, int connectTime, int socketTimeOut) {
        return postRequest(url, content, ContentType, charset, connectTime, socketTimeOut, null);
    }

    public static String postRequest(String url, String content, String ContentType, String charset, int connectTime, int socketTimeOut, Integer interfaceType) {
        long time1 = System.currentTimeMillis();
        String resultContent = "";
        CloseableHttpResponse httpResponse = null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        Integer statusCode = null;
        try {
            StringEntity stringEntity = new StringEntity(content, charset);
            //设置请求参数
            connectTime = connectTime <= 0 ? 30000 : connectTime;
            socketTimeOut = socketTimeOut <= 0 ? 30000 : socketTimeOut;
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTime).setSocketTimeout(socketTimeOut).build();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            httpPost.setEntity(stringEntity);

            if ("json".equals(ContentType)) {
                httpPost.setHeader("Content-type", "application/json");
            } else if ("html".equals(ContentType)) {
                httpPost.setHeader("Content-type", "text/html");
            } else if ("xml".equals(ContentType)) {
                httpPost.setHeader("Content-type", "application/xml");
            } else {
                httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
            }
            if (interfaceType != null) {
                Header[] headers = httpPost.getAllHeaders();
                List<String> headerStrList = new ArrayList<>();
                for (Header header : headers) {
                    headerStrList.add(header.getName() + "=" + header.getValue());
                }
            }
            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            resultContent = EntityUtils.toString(httpEntity, charset);

            return resultContent;

        } catch (Exception e) {
            e.printStackTrace();
            return resultContent;
        } finally {
            try {
                if (httpResponse != null) {
                    httpResponse.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            if (response == null) {
                logger.info("http请求url{}异常，返回结果null,", url);
                return null;
            }
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }





    /**
     * <pre>
     * 发送post请求
     * 将字符串参数以StringEntity的方式放入postEntity中
     * @param url 请求路径
     * @param content 请求内容
     * @return
     */
    public static String postRequest(String url, String content, String ContentType, int connectTime, int socketTimeOut) {
        return postRequest(url, content, ContentType, "UTF-8", 30000, 30000, null);
    }

    public static String postRequest(String url, String content, String ContentType, int connectTime, int socketTimeOut, int interfaceType) {
        return postRequest(url, content, ContentType, "UTF-8", 30000, 30000, interfaceType);
    }

    /**
     * <pre>
     * 发送get请求
     * @param url 请求路径
     * @param
     * @return
     */
    public static String getRequest(String url, List<BasicNameValuePair> list, int connectTime, int socketTimeOut) {
        String resultContent = "";
        CloseableHttpResponse httpResponse = null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        try {
            connectTime = connectTime <= 0 ? 20000 : connectTime;
            socketTimeOut = socketTimeOut <= 0 ? 30000 : socketTimeOut;
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(20000).setSocketTimeout(20000).build();
            //设置请求参数
            String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
            HttpGet httpGet = new HttpGet(url + "?" + params);
            httpGet.setConfig(requestConfig);
            httpResponse = httpClient.execute(httpGet);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            HttpEntity httpEntity = httpResponse.getEntity();
            resultContent = EntityUtils.toString(httpEntity, DEFAULT_CHARSET);

            return resultContent;
        } catch (IOException e) {
            e.printStackTrace();
            return resultContent;
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * <pre>
     * 获取请求数据流，转换为字符串
     * @param
     * @return
     * @throws IOException
     */
    public static String getStreamAsString(InputStream stream, String charset) throws IOException {
        try {
            Reader reader = new InputStreamReader(stream, charset);
            StringBuilder response = new StringBuilder();

            final char[] buff = new char[1024];
            int read = 0;
            while ((read = reader.read(buff)) > 0) {
                response.append(buff, 0, read);
            }

            return response.toString();
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
    }


    /**
     * 将map格式的数据，放入post请求的Entity中
     *
     * @param url
     * @param querys
     * @return
     */
    private static HttpPost postForm(String url, Map<String, Object> querys, String contentType) {
        HttpPost httpPost = new HttpPost(url);

        if ("json".equals(contentType)) {
            httpPost.setHeader("Content-type", "application/json");
        } else if ("html".equals(contentType)) {
            httpPost.setHeader("Content-type", "text/html");
        } else if ("xml".equals(contentType)) {
            httpPost.setHeader("Content-type", "application/xml");
        } else {
            httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
        }

        StringEntity stringEntity = null;
        if ("json".equals(contentType)) {
            JSONObject jsonObject = (JSONObject) JSON.toJSON(querys);
            stringEntity = new StringEntity(jsonObject.toJSONString(), Consts.UTF_8);
        } else {
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            Set<String> keySet = querys.keySet();
            for (String key : keySet) {
                nvps.add(new BasicNameValuePair(key, String.valueOf(querys.get(key))));
            }
            stringEntity = new UrlEncodedFormEntity(nvps, Consts.UTF_8);
        }
        httpPost.setEntity(stringEntity);
        return httpPost;
    }




    /**
     * 发送get请求
     * 利用Map结构的参数生成HttpEntity实体，使用UrlEncodeFormEntity对参数进行编码
     *
     * @param url
     * @param param
     * @param connectTime
     * @param socketTimeOut
     * @return java.lang.String
     * @author jzh
     * @date 2022-12-30 10:45
     **/
    public static String sendGetRequest(String url, Map<String, String> param, int connectTime, int socketTimeOut) {
        String resultContent = "";
        CloseableHttpResponse httpResponse = null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        try {
            connectTime = connectTime <= 0 ? 20000 : connectTime;
            socketTimeOut = socketTimeOut <= 0 ? 30000 : socketTimeOut;
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTime).setSocketTimeout(socketTimeOut).build();
            //设置请求参数
            List<BasicNameValuePair> paramList = new ArrayList<>();
            if (param != null) {
                for (Map.Entry<String, String> map : param.entrySet()) {
                    BasicNameValuePair pair = new BasicNameValuePair(map.getKey(), map.getValue());
                    paramList.add(pair);
                }
            }
            String params = EntityUtils.toString(new UrlEncodedFormEntity(paramList, Consts.UTF_8));
            HttpGet httpGet = new HttpGet(url + "?" + params);
            httpGet.setConfig(requestConfig);
            httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();

            resultContent = EntityUtils.toString(httpEntity, DEFAULT_CHARSET);

            return resultContent;
        } catch (IOException e) {
            e.printStackTrace();
            return resultContent;
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


}
